﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EquipOutfit : MonoBehaviour
{
    public GameObject[] outfits; // 角色的装备（如衣服、盔甲等）

    public Transform rootBone; // 角色的根骨骼

    void Start()
    {
        // 在当前对象的子物体中查找主骨骼 "Bip001"
        var selfRoot = this.transform.FindChildRecursiveByName("Bip001");

        for (int i = 0; i < outfits.Length; i++)
        {
            var of = outfits[i]; // 获取当前装备
            GameObject g = GameObject.Instantiate(of); // 复制装备对象
             
            //这里记载着新创建的，和引用他人创建的。用set，确保只同一个骨骼只被记录一次
            HashSet<GameObject> bindBones = new HashSet<GameObject>();
            SkinnedMeshRenderer sr = g.GetComponentInChildren<SkinnedMeshRenderer>(); // 获取装备的 SkinnedMeshRenderer
            var oldBone = sr.rootBone; // 记录原始的 rootBone
            var srRootBone = g.transform.FindChildRecursiveByName("Bip001"); // 查找装备的根骨骼

            // 获取装备上的 DynamicBone 组件
            DynamicBone [] dbones = g.GetComponentsInChildren<DynamicBone>();
            for (int k = 0; k < dbones.Length; k++)
            {
                var bone = dbones[k];
                List<Transform> hiters = new List<Transform>(); ;
                switch (bone.hiter)
                {
                    case NameCollider.Hair:
                        {
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 Spine1"));
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 Head"));
                        }
                        break;
                    case NameCollider.Pelvis:
                        {
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 Pelvis"));
                        }
                        break;

                    case NameCollider.Thigh:
                        {
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 Pelvis"));
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 L Thigh"));
                            hiters.Add(selfRoot.FindChildRecursiveByName("Bip001 R Thigh"));
                        }
                        break;
                }
                bone.m_Colliders.Clear();
                for (int n = 0; n < hiters.Count; n++)
                {
                    var hiter = hiters[n];
                    DynamicBoneCollider [] dbs  = hiter.GetComponents<DynamicBoneCollider>();
                    for (int z = 0; z < dbs.Length; z++)
                    {
                        var db = dbs[z];
                        if (null != db)
                        {
                            bone.m_Colliders.Add(db);
                        }
                    }
                    
                }
                // 重新映射 DynamicBone 的根骨骼，使其对齐到角色骨骼
                bone.m_Root = FindBone(bone.m_Root, selfRoot, srRootBone, bindBones);
            }
            // 重新映射装备的骨骼，使其匹配角色骨骼
            var bones = sr.bones;
            for (int j = 0; j < sr.bones.Length; j++)
            {
                bones[j] = FindBone(bones[j], selfRoot, srRootBone, bindBones); // 找到对应的骨骼
            }

            // 重新设置装备的 rootBone，使其匹配角色骨骼
            sr.rootBone = FindBone(sr.rootBone, selfRoot, srRootBone, bindBones);
            sr.bones = bones; // 更新骨骼列表

            // 让 SkinnedMeshRenderer 挂载到 rootBone 的父级，以保持层级关系
            sr.transform.parent = rootBone.parent;

            Outfit outfit = sr.gameObject.AddComponent<Outfit>();
            foreach (var g2 in bindBones)
            {
                
                outfit.Add(g2);
            }
           


            // 删除临时创建的装备对象（因为骨骼已经映射完成）
            GameObject.Destroy(g);
        }
    }

    /// <summary>
    /// 获取 Transform 在层级中的完整路径
    /// </summary>
    private string GetTransformPath(Transform transform)
    {
        if (transform == null)
            return "Null";

        string path = transform.name;
        while (transform.parent != null)
        {
            transform = transform.parent;
            path = transform.name + "/" + path;
        }
        return path;
    }
    
    /// <summary>
    /// 查找匹配的骨骼：
    /// 1. 根据装备骨骼在装备根骨骼下的相对层级，逐层在角色骨骼中查找对应的骨骼
    /// 2. 如果找不到，则创建相应的骨骼，并保持相对的变换
    /// </summary>
    private Transform FindBone(Transform bone, Transform baseBodeRoot, Transform outFitRoot, HashSet<GameObject> bindedBone)
    {
        if (bone == null || baseBodeRoot == null || outFitRoot == null)
            return null;

        // 记录 bone 在装备骨骼系统中的路径
        List<Transform> paths = new List<Transform>();
        var p = bone;
        while (p != null && p.name != outFitRoot.name)
        {
            paths.Add(p);
            p = p.parent;
        }

        // 在角色骨骼系统中查找对应的骨骼
        p = baseBodeRoot;
        for (int i = paths.Count - 1; i >= 0; i--)
        {
            var tf = paths[i];
            for (int j = 0; j < p.childCount; j++)
            {
                var c = p.GetChild(j);
                if (c.name == tf.name) // 如果找到了同名骨骼，则继续下一层
                {
                    p = c;
                    //检查是否动态创建的，增加引用计数器。
                    if (Outfit.ContainsKey(c.gameObject ))
                    {
                        bindedBone.Add(c.gameObject);
                    }
                    goto NEXT;
                }
            }

            // 如果没有找到对应的骨骼，则创建一个新的骨骼
            GameObject g2 = new GameObject(tf.name);
            g2.transform.parent = p; // 设为当前骨骼的子级
            g2.transform.localPosition = tf.transform.localPosition; // 继承原骨骼的位置
            g2.transform.localScale = tf.transform.localScale; // 继承缩放
            g2.transform.localRotation = tf.transform.localRotation; // 继承旋转
            bindedBone.Add(g2);
 
            p = g2.transform; // 继续下一层

            NEXT:
            continue;
        }

        return p; // 返回最终找到或创建的骨骼
    }
}
